package com.opencee.cloud.base.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.opencee.boot.db.mybatis.service.impl.SupperServiceImpl;
import com.opencee.cloud.base.constants.BaseAccountType;
import com.opencee.cloud.base.entity.BaseAccountCredentialEntity;
import com.opencee.cloud.base.entity.BaseOrganizationEntity;
import com.opencee.cloud.base.entity.BaseRoleEntity;
import com.opencee.cloud.base.entity.BaseUserEntity;
import com.opencee.cloud.base.mapper.BaseUserMapper;
import com.opencee.cloud.base.service.*;
import com.opencee.cloud.base.vo.BaseOrganizationVO;
import com.opencee.cloud.base.vo.BaseRoleVO;
import com.opencee.cloud.base.vo.BaseUserInfoVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户信息 服务实现类
 * </p>
 *
 * @author liuyadu
 * @since 2021-04-16
 */
@Service
public class BaseUserServiceImpl extends SupperServiceImpl<BaseUserMapper, BaseUserEntity> implements IBaseUserService {

    @Autowired
    private IBaseAccountCredentialService accountCredentialService;
    @Autowired
    private IBaseRoleGrantedService roleGrantedService;
    @Autowired
    private IBaseOrganizationService organizationService;
    @Autowired
    private IBaseOrganizationUserService organizationUserService;


    /**
     * 添加系统用户
     *
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(BaseUserEntity entity) {
        if (entity.getStatus() == null) {
            entity.setStatus(1);
        }
        entity.setDeleted(0);
        // 设置工号
        entity.setUserNo(generateUserCode());
        if (StringUtils.isBlank(entity.getUserName())) {
            entity.setUserName(entity.getUserNo());
        }
        //保存系统用户信息
        boolean flag = super.save(entity);
        return flag;
    }

    /**
     * 生成工号
     *
     * @return
     */
    @Override
    public String generateUserCode() {
        String no = DateUtil.format(new Date(), "yyyyMMdd") + (count() + 1);
        return no;
    }

    /**
     * 保存用户信息
     *
     * @param info
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveUserInfo(BaseUserInfoVO info) {
        if (info.getUserId() == null) {

            boolean flag = this.save(info);

            BaseAccountCredentialEntity accountCredential = new BaseAccountCredentialEntity();
            accountCredential.setUserId(info.getUserId());
            accountCredential.setCredentials(info.getPassword());
            if (flag && StringUtils.isNotBlank(info.getUserName())) {
                accountCredential.setAccount(info.getUserName());
                accountCredential.setAccountType(BaseAccountType.USERNAME.name());
                accountCredential.setVerified(StringUtils.isEmpty(accountCredential.getCredentials()) ? false : true);
                //默认注册用户名账户
                accountCredentialService.save(accountCredential);
            }

            if (flag && StringUtils.isNotBlank(info.getEmail()) && Validator.isEmail(info.getEmail())) {
                //注册email账号登陆
                accountCredential.setVerified(false);
                accountCredential.setAccount(info.getEmail());
                accountCredential.setAccountType(BaseAccountType.EMAIL.name());
                accountCredentialService.save(accountCredential);
            }

            if (flag && StringUtils.isNotBlank(info.getMobile()) && Validator.isMobile(info.getMobile())) {
                //注册手机号账号登陆
                accountCredential.setVerified(false);
                accountCredential.setAccount(info.getMobile());
                accountCredential.setAccountType(BaseAccountType.MOBILE.name());
                accountCredentialService.save(accountCredential);
            }
        } else {
            info.setUserName(null);
            info.setPassword(null);
            this.updateById(info);
        }

        if (info.getOrgId() != null) {
            // 更新用户直属部门
            organizationUserService.updateDirect(info.getOrgId(), info.getUserId());
        }
    }

    /**
     * 获取用户
     *
     * @param userId
     * @return
     */
    @Override
    public BaseUserInfoVO getUserInfo(Long userId) {
        BaseUserEntity entity = getById(userId);
        if (entity == null) {
            return null;
        }
        BaseUserInfoVO info = new BaseUserInfoVO();
        BeanUtils.copyProperties(entity, info);
        List<BaseOrganizationVO> orgList = organizationUserService.listByUserId(userId);
        List<BaseRoleEntity> roleList = roleGrantedService.listRolesByUserId(userId);
        List<BaseRoleVO> baseRoleVOList = roleList.stream().map(t -> {
            BaseRoleVO vo = new BaseRoleVO();
            vo.setId(t.getId());
            vo.setCode(t.getCode());
            vo.setName(t.getName());
            return vo;
        }).collect(Collectors.toList());
        info.setOrganizations(orgList);
        info.setRoles(baseRoleVOList);

        if (entity.getOrgId() != null) {
            BaseOrganizationEntity org = organizationService.getById(entity.getOrgId());
            info.setOrgName(org.getName());
        }
        return info;
    }

    /**
     * 批量查询并返回Map
     *
     * @param userIds
     * @return
     */
    @Override
    public Map<Long, BaseUserEntity> mapByIds(Set<Long> userIds) {
        List<BaseUserEntity> list = listByIds(userIds);
        Map<Long, BaseUserEntity> map = new HashMap<>(8);
        list.forEach(t -> {
            map.put(t.getUserId(), t);
        });
        return map;
    }

    /**
     * 更新用户直属部门
     *
     * @param userId
     * @param orgId
     */
    @Override
    public void updateOrgId(Long userId, Long orgId) {
        BaseUserEntity entity = new BaseUserEntity();
        entity.setOrgId(orgId);
        entity.setUserId(userId);
        this.updateById(entity);
    }

    /**
     * 批量更新直属部门
     *
     * @param oldOrgIds
     * @param newOrgId
     */
    @Override
    public void batchUpdateOrgId(Set<Long> oldOrgIds, Long newOrgId) {
        if (CollectionUtils.isEmpty(oldOrgIds)) {
            return;
        }
        QueryWrapper<BaseUserEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(BaseUserEntity::getOrgId, oldOrgIds);
        BaseUserEntity entity = new BaseUserEntity();
        entity.setOrgId(newOrgId);
        this.update(entity, wrapper);
    }


}
